<?php
/**
 * Description:
 *
 * @author      Eden
 * @datetime    2017/1/13 00:50
 * @copyright   WuHan HuQi Technology Co.,Ltd.
 * @url         http://cnhuqi.com
 */

use Wechat\Loader;

class Order extends WX_Controller
{

    // 商品金额
    private $goodsPrice = 0;

    //

    /**
     * 初始化
     * @throws Exception
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * 订单列表
     */
    public function orderLists()
    {
        if (!empty($this->openId)) {
            $orderType = $this->input->get('orderType');
            $page = $this->input->get('page');
            $page = empty($page) ? 1 : intval($page);
            $this->load->model('wx/user/Order_Model', 'order');
            $orders = $this->order->getOrderLists($this->userid, $this->userType, $orderType, $page);
            $this->output(!empty($orders) ? $orders : []);
        } else {
            $this->outputError(self::NO_LOGIN);
        }
    }

    /**
     * 添加订单
     */
    public function add()
    {
        if(!empty($this->openId)) {

            if ($this->input->method(true) != 'POST') {
                $this->outputError('非法请求');
            }
            $posts = $this->input->post();
            if (empty($posts['expressId']) || !isset($posts['totalPrice']) || empty($posts['goodsPrice'])) {
                $this->outputError('参数错误');
            }

            // 商品
            $this->load->model('wx/user/Car_Model', 'car');
            $goods = $this->car->getLists($this->userid, true);
            if (empty($goods)) {
                $this->outputError('未选择任何商品');
            }

            // 优惠券
            $ticketPrice = 0;
            if (!empty($posts['ticketId'])) {
                // 说明使用过优惠券
                $ticketPrice = $this->_getAndCheckTicket($posts['ticketId']);
                if ($ticketPrice != $posts['ticketPrice']) {
                    $this->outputError('优惠券金额错误');
                }
            }

            // 使用余额
            if (!empty($posts['useBalance'])) {
                $this->_checkUserBalance($posts['useBalance']);
            }

            // 生成多个订单
            $this->load->model('common/ExpressPrice_Model', 'e');
            $exp = $this->e->price($this->userid);
            if ($exp['total'] != $posts['expressPrice']) {
                $this->outputError('物流费用不符');
                return false;
            }

            // 生成订单
            $data = [
                'userType' => $this->userType,
                'goods' => $goods,
                'expressId' => $posts['expressId'],
                'totalPrice' => $posts['totalPrice'],
                'goodsPrice' => $this->goodsPrice,
                'expressPrice' => $posts['expressPrice'],
                'balance' => $posts['useBalance'],
                'voucherPrice' => $ticketPrice,
                'voucherId' => $posts['ticketId'],
                'integral' => value($posts, 'integralNum', 0),
                'integralPrice' => value($posts, 'integralPrice', 0),
                'message' => value($posts, 'message', ''),
                'userId' => $this->userid
            ];

            $this->load->model('common/Order_Model', 'order');
            $order = $this->order->add($data, $goods, $exp);
            if ($order) {

                // 删除购物车
                $cacheKey = $this->openId . ':CarCount';
                $this->cache->redis->delete($cacheKey);

                // 使用余额方式支付了,不需要微信额外支付
                if ($posts['totalPrice'] == 0) {
                    $this->_getScore($this->userid, $posts['totalPrice'] / 100);
                    $this->output(['needPay' => false]);
                }

                Loader::config($this->options);
                $pay = Loader::get('pay');
                $notifyUrl = APP_URL . '/wx/notify';
                $prepayId = $pay->getPrepayId($this->openId, '丘丘谷', $order, $data['totalPrice'], $notifyUrl);
                if ($prepayId) {
                    $this->load->model('common/Pay_Model', 'pay');
                    $this->pay->saveWxBuy([
                        'sn' => $order,
                        'userid' => $this->userid,
                        'openid' => $this->openId,
                        'total_fee' => $data['totalPrice'],
                        'prepay_id' => $prepayId,
                        'status' => 1
                    ]);
                    $jsSDK = $pay->createMchPay($prepayId);
                    $this->output([
                        'needPay' => true,
                        'jssdk' => $jsSDK,
                        'order' => [
                            'orderId' => $order
                        ]
                    ]);
                } else {
                    // 没有获取到 Prepay ID
                    $this->outputError('下单失败');
                }
            } else {
                $this->outputError($this->order->getError());
            }
        } else {
            $this->outputError(self::NO_LOGIN);
        }
    }

    /**
     * 获取积分
     * @param $order
     * @return bool
     */
    private function _getScore($userId, $score)
    {
        $db = clone($this->db);
        $db->where('id', $userId);
        $db->set('score', "score+{$score}", false);
        $db->update("user");

    }

    private function _checkUserBalance($balance = 0)
    {
        $this->load->model('wx/user/User_Model', 'user');
        $user = $this->user->getUserInfoById($this->userid);
        if (empty($user)) {
            $this->outputError('非法用户');
            return false;
        }

        if ($user['amount'] < $balance) {
            $this->outputError('用户余额不足');
            return false;
        }
        return true;
    }

    /**
     * @param $ticketID
     * @return mixed
     */
    private function _getAndCheckTicket($ticketID)
    {
        $this->load->model('wx/Ticket_Model', 'ticket');
        $uTicket = $this->ticket->getTicketForUser($this->userid, $ticketID);
        if (empty($uTicket)) {
            $this->outputError('用户无此优惠券');
        }

        if ($uTicket['used'] != 0) {
            $this->outputError('该优惠券已使用');
        }

        $ticket = $this->ticket->getTicketById($ticketID);
        if (empty($ticket)) {
            $this->outputError('无此优惠券');
        }

        $timeStart = strtotime($ticket['time_start']);
        $timeEnd = strtotime($ticket['time_end']);
        $nowTime = time();

        if ($timeStart > $nowTime || $timeEnd < $nowTime) {
            $this->outputError('优惠券未开始或已过期');
        }

        if ($ticket['status'] != 6) {
            $this->outputError('该优惠券无法使用');
        }

        if ($ticket['wechat'] != 1) {
            $this->outputError('微信端无法使用该优惠券');
        }

        if ($ticket['limit_amount'] > $this->goodsPrice) {
            $this->outputError('商品金额低于优惠券额度限制');
        }

        return $ticket['amount'];
    }

    /**
     * 检查价格
     * @param $goods
     * @param $posts
     * @return bool
     */
    private function _getExpPrice($goods)
    {
        $config = $this->_getShippingCosts();
        $totalWeight = $totalAmount = 0;
        $totalPrice = 0;

        foreach($goods as $item) {
            $num = $item['num'];
            $goodsPerPrice = $item['price'];
            $this->goodsPrice += $num * $goodsPerPrice;
            if ($item['expType'] == 1) {
                // 按重量
                if ($config['payer'] == 'seller' ) {
                    // 卖家包邮
                    $totalPrice += 0;
                } else {
                    // 用户承担邮费
                    $totalWeight += $num * $item['expressWeight'];   // 总重量
                }
            } else {
                // 一口价
                $price = $item['expAmount'];
                $totalPrice += $price * $num;
            }
        }

        // 物流重量为 0
        if ($totalWeight == 0) {
            return $totalPrice;
        }

        $costs = $config['costs'];
        // 重量小于首重
        if ($totalWeight < $costs['firstWeight']) {
            return $costs['firstCost'] * 100 + $totalPrice;
        }

        $left = $totalWeight - $costs['firstWeight'];
        $expPrice = ceil($left / $costs['incrWeight']) * $costs['incrCost'] + $costs['firstCost'];
        return $expPrice * 100 + $totalPrice;
    }

    /**
     * 获取跟客户端一样的物流配置
     * @return array
     */
    private function _getShippingCosts()
    {
        $default = array(
            'payer' => 'seller',
            'costs' => []
        );
        // 前期只考虑到统一的价格的情况,没有进行区域区分
        $db = clone($this->db);
        $q = $db->get_where('express_template', array('using' => 1));
        $row = $q->row_array();
        if (!$row) {
            return $default;
        }

        if ($row['payer'] == 'seller') {
            return $default;
        }

        $payer = $row['payer'];
        if ($row['payType'] == 'weight') {
            $q = $this->db->get_where('express_weight', array('tmpId' => $row['id']));
            $row = $q->row_array();
            if (empty($row)) {
                return $default;
            }
            $default['payer'] = $payer;
            $default['costs'] = array(
                'firstWeight' => doubleval($row['firstWeight']),
                'firstCost' => doubleval($row['firstCost']),
                'incrWeight' => doubleval($row['incrWeight']),
                'incrCost' => doubleval($row['incrCost'])
            );
        }

        return $default;
    }

    /**
     * 获取购物车中的商品
     */
    public function detail()
    {
        if (!empty($this->openId)) {

            $addressId = $this->input->get('addressId');
            $this->load->model('wx/user/Address_Model', 'addr');
            if (empty($addressId)) {
                // 默认地址
                $address = $this->addr->getOne($this->userid);
            } else {
                $address = $this->addr->getItem($addressId);
            }

            // 商品
            $this->load->model('wx/user/Car_Model', 'car');
            $goods = $this->car->getLists($this->userid, $this->userType, true);
            if (empty($goods)) {
                $this->outputError('未选择任何商品');
            }

            // 用户
            $this->load->model('wx/user/User_Model', 'user');
            $user = $this->user->getUserInfoById($this->userid);

            $this->load->model('common/ExpressPrice_Model', 'e');
            $exp = $this->e->price($this->userid);
            $this->output([
                'address' => !empty($address) ? $address : [],
                'goods' => $goods,
                'user' => $user,
                'exp' => $exp
            ]);

        } else {
            $this->outputError('用户未登录');
        }
    }

    /**
     * 物流配置
     */
    public function shipping()
    {
        $default = array(
            'payer' => 'seller',
            'costs' => new stdClass()
        );

        // 前期只考虑到统一的价格的情况,没有进行区域区分
        do {
            $db = clone($this->db);
            $q = $db->get_where('express_template', array('using' => 1));
            $row = $q->row_array();
            if (!$row) {
                break;
            }

            if ($row['payer'] == 'seller') {
                break;
            }

            $payer = $row['payer'];
            if ($row['payType'] == 'weight') {
                $q = $this->db->get_where('express_weight', array('tmpId' => $row['id']));
                $row = $q->row_array();
                if (empty($row)) {
                    break;
                }
                $default['payer'] = $payer;
                $default['costs'] = array(
                    'firstWeight' => doubleval($row['firstWeight']),
                    'firstCost' => doubleval($row['firstCost']),
                    'incrWeight' => doubleval($row['incrWeight']),
                    'incrCost' => doubleval($row['incrCost'])
                );
            }
        } while(false);

        $this->output($default);
    }

    /**
     * 修改
     */
    public function modifyStatus()
    {
        if (!empty($this->openId)) {
            $orderId = $this->input->post('orderId');
            $status = $this->input->post('status');
            $uuid = $this->input->post('uuid');

            if (empty($status) || (empty($uuid) && empty($orderId))) {
                $this->outputError('参数错误');
            }

            $this->load->model('wx/user/Order_Model', 'order');
            $res = $this->order->modify($orderId, $uuid, $status);
            if ($res) {
                $this->output('修改成功');
            } else {
                $this->outputError('修改失败');
            }
        } else {
            $this->outputError(self::NO_LOGIN);
        }

    }

    /**
     * 修改状态
     */
    public function chgStatus()
    {
        if (!empty($this->openId)) {

            $orderId = $this->input->post('orderId');
            $status = $this->input->post('status');
            $uuid = $this->input->post('uuid');

            $this->load->model('wx/user/Order_Model', 'order');
            $res = $this->order->chgStatus($orderId, $uuid, $status);
            if ($res) {
                $this->output('修改成功');
            } else {
                $this->outputError('修改失败');
            }

        } else {
            $this->outputError(self::NO_LOGIN);
        }
    }

    /**
     * 订单详情
     */
    public function content()
    {
        if (!empty($this->openId)) {

            $orderid = $this->input->get('orderId');
            $addressId = $this->input->get('addressId');
            $addressId = !empty($addressId) ? $addressId : 0;
            if (empty($orderid)) {
                $this->outputError('无效订单号');
            }

            $this->load->model('wx/user/Order_Model', 'order');
            $content = $this->order->getContent($orderid, $this->userType, $addressId);

            if ($content) {
                $this->output($content);
            } else {
                $error = $this->order->getError();
                $this->outputError(!empty($error) ? $error : '无法加载详情');
            }

        } else {
            $this->outputError(parent::NO_LOGIN);
        }
    }

    public function express()
    {
        if (!empty($this->openId)) {

            $orderid = $this->input->get('orderId');
            if (empty($orderid)) {
                $this->outputError('无效订单号');
            }

            // 查询订单号
            $query = $this->db->get_where('user_order_express', array('orderId' => $orderid));
            $express = $query->row_array();

            if (empty($express)) {
                $this->output([]);
            }

            $this->load->library('util/Util_AliExpress', null, 'AliExpress');
            $res = $this->AliExpress->ask($express['simpleName'], $express['expressNo']);

            $error = '';
            if ($res && is_array($res)) {
                $result = value($res, 'showapi_res_body');
                if (!empty($result) && isset($result['ret_code']) && $result['ret_code'] == 0) {
                    // 成功
                    $send = array(
                        'expressNo' => $express['expressNo'],
                        'update' => $result['update'],
                        'updateStr' => $result['updateStr'],
                        'tel' => $result['tel'],
                        'expSpellName' => $result['expSpellName'],
                        'expTextName' => $result['expTextName'],
                        'data' => value($result, 'data')
                    );

                    $this->output($send);

                } else {
                    $error = !empty($result['msg']) ? $result['msg'] : '暂无跟踪信息';
                }
            } else {
                $error = '查询失败';
            }
            $this->outputError($error);
        } else {
            $this->outputError(parent::NO_LOGIN);
        }
    }

    /**
     * 再来一单
     */
    public function buyMore()
    {
        if (!empty($this->openId)) {

            $orderId = $this->input->post('orderId');
            if (empty($orderId)) {
                $this->outputError('参数错误');
            }

            $this->load->model('wx/user/Order_Model', 'order');
            $newOrderId = $this->order->buyMore2($orderId);
            if (!$newOrderId) {
                $error = $this->order->getOrderError();
                $this->outputError($error ? $error : '下单失败');
            } else {
                $cacheKey = $this->openId . ':CarCount';
                $this->cache->redis->delete($cacheKey);
                $this->output(['msg' => 'success']);
            }
        } else {
            $this->outputError(self::NO_LOGIN);
        }
    }

    /**
     * 立即支付
     */
    public function payNow()
    {
        if (!empty($this->openId)) {

            $message = $this->input->post('message');
            $orderId = $this->input->post('orderId');

            if (empty($orderId)) {
                $this->outputError('参数错误');
            }

            $this->load->model('wx/user/Order_Model', 'o');
            $orders = $this->o->getOrder($orderId);
            if (empty($orders)) {
                $this->outputError('订单不存在');
            }

            $balance = 0;
            $total = 0;
            foreach($orders as $item) {
                $total += $item['totalPrice'];
                $balance = $item['balancePrice'];
            }

            if (!empty($message)) {
                $this->o->updateField($orderId, [
                    'message' => $message,
                ]);
            }

            // 判断余额够用
            if (!empty($balance)) {
                if (!$this->_checkUserBalance($balance)) {
                    return false;
                }

                // 扣个人余额
                $this->_descUserAmount($this->userid, $balance);

                if ($total == $balance) {
                    $this->o->updateField($orderId, [
                        'payStatus' => 6,
                        'status' => 'Pending'
                    ]);

                    $this->_getScore($this->userid, ceil($total / 100));
                    $this->output([
                        'needPay' => false,
                    ]);
                }
            }

            Loader::config($this->options);
            $pay = Loader::get('pay');
            $notifyUrl = APP_URL . '/wx/notify';
            $totalFee = $balance > 0 ? $total - $balance : $total;
            $prepayId = $pay->getPrepayId($this->openId, '丘丘谷', $orderId, $totalFee, $notifyUrl);
            if ($prepayId) {
                $this->load->model('common/Pay_Model', 'pay');
                $this->pay->saveWxBuy([
                    'sn' => $orderId,
                    'userid' => $this->userid,
                    'openid' => $this->openId,
                    'total_fee' => $totalFee,
                    'prepay_id' => $prepayId,
                    'status' => 1
                ]);
                $jsSDK = $pay->createMchPay($prepayId);
                $this->output([
                    'needPay' => true,
                    'jssdk' => $jsSDK,
                    'order' => ['orderId' => $orderId]
                ]);
            } else {
                $this->outputError('下单失败');
            }
        } else {
            $this->outputError(self::NO_LOGIN);
        }
    }

    public function _descUserAmount($userId, $amount)
    {
        $db = clone($this->db);
        $db->where('id', $userId);
        $db->set('amount', "amount+{$amount}", false);
        $db->set('amountBuy', "amountBuy+{$amount}", false);
        $db->set('amountUnLimit', "amountUnLimit+{$amount}", false);
        $db->update("user");
    }

    public function afterPay()
    {
        if (!empty($this->openId)) {
            $this->output('支付成功');
            return true;

            $orderId = $this->input->post('orderId');
            $status = $this->input->post('status');
            if (empty($orderId) || empty($status) || $status != 'success') {
                $this->outputError('非法请求');
            }

            // 修改订单信息
            $this->load->model('wx/user/Order_Model', 'user');
            if ($this->user->afterPaid($orderId)) {
                $this->output('支付成功');
            }
        } else {
            $this->outputError(self::NO_LOGIN);
        }

    }

    /**
     * 确认成功
     */
    public function confirm()
    {
        if (!empty($this->openId)) {

            $orderId = $this->input->post('orderId');;
            if (empty($orderId)) {
                $this->outputError('参数错误');
            }

            $this->load->model('wx/user/Order_Model', 'order');
            if (!$this->order->chgStatus($orderId, '', 'Complete')) {
                $this->outputError('确认失败');
            } else {
                $this->output('确认成功');
            }

        } else {
            $this->outputError(self::NO_LOGIN);
        }
    }

    /**
     * 评论
     */
    public function comment()
    {
        if (!empty($this->openId)) {

            $post = $this->input->post();
            if (empty($post) || empty($post['express']) || empty($post['orderId']) || empty($post['goods'])) {
                $this->outputError('参数错误');
            }

            $this->load->model('wx/user/Order_Model', 'order');
            if ($this->order->commentsGoods($post, $this->userid)) {
                $this->output('评论成功');
            } else {
                $this->outputError('评论失败');
            }
        } else {
            $this->outputError(self::NO_LOGIN);
        }
    }

    /**
     * 退款
     */
    public function refund()
    {
        if (!empty($this->openId)) {
            $orderId = $this->input->post('orderId');
            $message = $this->input->post('message');
            if (empty($orderId)) {
                $this->outputError('参数错误');
            }

            $this->load->model('wx/user/Order_Model', 'order');
            // check order
            $order = $this->order->getOrderByID($orderId);
            if (empty($order)) {
                $this->outputError('无此订单');
            }

            if (!in_array($order['status'], ['Complete', 'Pending', "Dispatch"])) {
                $this->outputError('该订单无法申请退款');
                die;
            }

            if ($this->order->doRefund($order, $this->userid, $message)) {
                $this->output('申请成功');
            } else {
                $this->outputError('退款失败');
            }

        } else {
            $this->outputError(self::NO_LOGIN);
        }
    }

}



















